home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / recov / recovProc.c < prev   
C/C++ Source or Header  |  1992-12-18  |  9KB  |  380 lines

  1. /* 
  2.  * recovProc.c --
  3.  *
  4.  *    Recov_Proc is the process that periodically checks the status
  5.  *    of other hosts.  It is pretty simple, but its in its own file
  6.  *    because of the monitor lock needed to synchronize access to
  7.  *    its list of interesting hosts.
  8.  *
  9.  * Copyright 1989 Regents of the University of California
  10.  * Permission to use, copy, modify, and distribute this
  11.  * software and its documentation for any purpose and without
  12.  * fee is hereby granted, provided that the above copyright
  13.  * notice appear in all copies.  The University of California
  14.  * makes no representations about the suitability of this
  15.  * software for any purpose.  It is provided "as is" without
  16.  * express or implied warranty.
  17.  */
  18.  
  19. #ifndef lint
  20. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/recov/recovProc.c,v 1.16 92/12/13 18:20:13 mgbaker Exp $ SPRITE (Berkeley)";
  21. #endif /* not lint */
  22.  
  23. #include <sprite.h>
  24. #include <recov.h>
  25. #include <sync.h>
  26. #include <rpc.h>
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29.  
  30. /*
  31.  * A host is "pinged" (to see when it reboots) at an interval determined by
  32.  * rpcPingSeconds.
  33.  */
  34. int recovPingSeconds = 30;
  35. /*
  36.  * Whether or not to ping at absolute intervals instead of 30 after the last
  37.  * ping finished.  This is used for testing the affects of the synchronization
  38.  * of client pinging on the servers.  The condition variable gets its 
  39.  * own lock because that seemed cleaner than using the monitor lock 
  40.  * (the condition variable has nothing to do with the data protected 
  41.  * by the monitor lock).  The condition variable is an extern so that it 
  42.  * can be referenced by Proc_Dump().
  43.  */
  44. Boolean            recov_AbsoluteIntervals = TRUE;
  45. Timer_QueueElement    recovIntervalElement;
  46. Sync_Condition        recovPingCondition;
  47. static Sync_Lock    recovPingConditionLock;
  48. /*
  49.  * A list of hosts to ping is used by Recov_Proc.
  50.  */
  51. typedef struct RecovPing {
  52.     List_Links links;
  53.     int spriteID;    /* The host we are interested in */
  54.     Boolean active;    /* TRUE if we are really interested in it */
  55. } RecovPing;
  56.  
  57. List_Links recovPingListHdr;
  58. List_Links *recovPingList = &recovPingListHdr;
  59. /*
  60.  * Access to the ping list is monitored
  61.  */
  62. static Sync_Lock pingListLock;
  63. #define LOCKPTR (&pingListLock)
  64.  
  65. static RecovPing *FirstHostToCheck _ARGS_((void));
  66. static RecovPing *NextHostToCheck _ARGS_((RecovPing *pingPtr));
  67. static void Deactivate _ARGS_((RecovPing *pingPtr));
  68. static void PingInterval _ARGS_((Timer_Ticks time, ClientData clientData));
  69.  
  70.  
  71. /*
  72.  *----------------------------------------------------------------------
  73.  *
  74.  * PingInterval --
  75.  *
  76.  *    Set up the callback routine used for recov pinging.
  77.  *
  78.  * Results:
  79.  *    None.
  80.  *
  81.  * Side effects:
  82.  *    None.
  83.  *
  84.  *----------------------------------------------------------------------
  85.  */
  86. /*ARGSUSED*/
  87. static void
  88. PingInterval(time, clientData)
  89.     Timer_Ticks    time;
  90.     ClientData    clientData;
  91. {
  92.     (void)Sync_GetLock(&recovPingConditionLock);
  93.     Sync_Broadcast(&recovPingCondition);
  94.     (void)Sync_Unlock(&recovPingConditionLock);
  95.     Timer_ScheduleRoutine(&recovIntervalElement, TRUE);
  96.  
  97.     return;
  98. }
  99.  
  100.  
  101. /*
  102.  *----------------------------------------------------------------------
  103.  *
  104.  * RecovPingInit --
  105.  *
  106.  *    Set up the data structures used by the recovery ping process.
  107.  *
  108.  * Results:
  109.  *    None.
  110.  *
  111.  * Side effects:
  112.  *    None.
  113.  *
  114.  *----------------------------------------------------------------------
  115.  */
  116.  
  117. void
  118. RecovPingInit()
  119. {
  120.     Sync_LockInitDynamic(&pingListLock, "Recov:pingListLock");
  121.     Sync_LockInitDynamic(&recovPingConditionLock,
  122.              "Recov:recovPingConditionLock");
  123.     List_Init(recovPingList);
  124.     if (recov_AbsoluteIntervals) {
  125.     recovIntervalElement.routine = PingInterval;
  126.     recovIntervalElement.clientData = 0;
  127.     recovIntervalElement.interval =
  128.         timer_IntOneSecond * recovPingSeconds;
  129.     Timer_ScheduleRoutine(&recovIntervalElement, TRUE);
  130.     }
  131.     return;
  132. }
  133.  
  134.  
  135.  
  136. /*
  137.  *----------------------------------------------------------------------
  138.  *
  139.  * Recov_Proc --
  140.  *
  141.  *    Recovery process that periodically pings other hosts to verify
  142.  *    that they are still and if they have rebooted since we last
  143.  *    heard from them.
  144.  *
  145.  * Results:
  146.  *    None.
  147.  *
  148.  * Side effects:
  149.  *    None.
  150.  *
  151.  *----------------------------------------------------------------------
  152.  */
  153.  
  154. void
  155. Recov_Proc()
  156. {
  157.     RecovPing *pingPtr;
  158.     Time wait;
  159.     int check;
  160.  
  161.     while (TRUE) {
  162.     /*
  163.      * Calculate wait period inside loop so we can change it
  164.      * on the fly.
  165.      */
  166.     if (!recov_AbsoluteIntervals) {
  167.         Time_Multiply(time_OneSecond, recovPingSeconds, &wait);
  168.         Sync_WaitTime(wait);
  169.     } else {
  170.         (void) Sync_GetLock(&recovPingConditionLock);
  171.         (void) Sync_SlowWait(&recovPingCondition, &recovPingConditionLock,
  172.                  FALSE);
  173.         (void) Sync_Unlock(&recovPingConditionLock);
  174.     }
  175.     if (sys_ShuttingDown) {
  176.         printf("Recov_Proc exiting.\n");
  177.         break;
  178.     }
  179.     /*
  180.      * Scan the ping list looking for hosts we should check.
  181.      * We'll ping them if there hasn't been recent message traffic,
  182.      * and we'll deactivate our interest if there is no set
  183.      * of reboot call backs associated with the host.
  184.      */
  185.     if (recov_BlockingRpcs) {
  186.         continue;
  187.     }
  188.     pingPtr = FirstHostToCheck();
  189.     while (pingPtr != (RecovPing *)NIL) {
  190.         check = RecovCheckHost(pingPtr->spriteID);
  191.         if (check > 0) {
  192.         int    oldState;
  193.         int    newState;
  194.         /*
  195.          * Only put in ping event if the host wasn't alive last
  196.          * time and it is this time, or the state otherwise changed.
  197.          * Otherwise, all we see are ping events.
  198.          */
  199.         newState = Recov_GetHostState(pingPtr->spriteID);
  200.         oldState = Recov_GetHostOldState(pingPtr->spriteID);
  201.         if (newState != oldState) {
  202.             RECOV_TRACE(pingPtr->spriteID,
  203.             RecovGetLastHostState(pingPtr->spriteID),
  204.             RECOV_CUZ_PING_CHK);
  205.             Recov_SetHostOldState(pingPtr->spriteID, newState);
  206.         }
  207.         recov_Stats.pings++;
  208.         Rpc_Ping(pingPtr->spriteID);
  209.         } else if (check == 0) {
  210.         recov_Stats.pingsSuppressed++;
  211.         } else {
  212.         Deactivate(pingPtr);
  213.         }
  214.         pingPtr = NextHostToCheck(pingPtr);
  215.     }
  216.     }
  217.     Proc_Exit(0);
  218. }
  219.  
  220. /*
  221.  *----------------------------------------------------------------------
  222.  *
  223.  * FirstHostToCheck --
  224.  *
  225.  *    This pulls the first host to check off the ping list.
  226.  *
  227.  * Results:
  228.  *    A pingPtr.
  229.  *
  230.  * Side effects:
  231.  *    None.
  232.  *
  233.  *----------------------------------------------------------------------
  234.  */
  235.  
  236. static RecovPing *
  237. FirstHostToCheck()
  238. {
  239.     RecovPing *pingPtr;
  240.  
  241.     LOCK_MONITOR;
  242.  
  243.     if (List_IsEmpty(recovPingList)) {
  244.     pingPtr = (RecovPing *)NIL;
  245.     } else {
  246.     pingPtr = (RecovPing *)List_First(recovPingList);
  247.     }
  248.  
  249.     UNLOCK_MONITOR;
  250.     return(pingPtr);
  251. }
  252.  
  253. /*
  254.  *----------------------------------------------------------------------
  255.  *
  256.  * NextHostToCheck --
  257.  *
  258.  *    This pulls the next host to check off the ping list.
  259.  *
  260.  * Results:
  261.  *    A pingPtr.
  262.  *
  263.  * Side effects:
  264.  *    None.
  265.  *
  266.  *----------------------------------------------------------------------
  267.  */
  268.  
  269. static RecovPing *
  270. NextHostToCheck(pingPtr)
  271.     RecovPing *pingPtr;
  272. {
  273.     LOCK_MONITOR;
  274.  
  275.     pingPtr = (RecovPing *)List_Next((List_Links *)pingPtr);
  276.     if (List_IsAtEnd(recovPingList, (List_Links *)pingPtr)) {
  277.     pingPtr = (RecovPing *)NIL;
  278.     }
  279.  
  280.     UNLOCK_MONITOR;
  281.     return(pingPtr);
  282. }
  283.  
  284. /*
  285.  *----------------------------------------------------------------------
  286.  *
  287.  * RecovAddHostToPing --
  288.  *
  289.  *    Add an entry to the ping list.
  290.  *
  291.  * Results:
  292.  *    None.
  293.  *
  294.  * Side effects:
  295.  *    List_Insert.
  296.  *
  297.  *----------------------------------------------------------------------
  298.  */
  299.  
  300. void
  301. RecovAddHostToPing(spriteID)
  302.     int spriteID;
  303. {
  304.     RecovPing *pingPtr;
  305.     LOCK_MONITOR;
  306.  
  307.     LIST_FORALL(recovPingList, (List_Links *)pingPtr) {
  308.     if (pingPtr->spriteID == spriteID) {
  309.         if (!pingPtr->active) {
  310.         recov_Stats.numHostsPinged++;
  311.         pingPtr->active = TRUE;
  312.         }
  313.         UNLOCK_MONITOR;
  314.         return;
  315.     }
  316.     }
  317.     pingPtr = (RecovPing *)malloc(sizeof(RecovPing));
  318.     recov_Stats.numHostsPinged++;
  319.     pingPtr->active = TRUE;
  320.     pingPtr->spriteID = spriteID;
  321.     List_InitElement((List_Links *)pingPtr);
  322.     List_Insert((List_Links *)pingPtr, LIST_ATREAR(recovPingList));
  323.  
  324.     UNLOCK_MONITOR;
  325. }
  326.  
  327. /*
  328.  *----------------------------------------------------------------------
  329.  *
  330.  * Deactivate --
  331.  *
  332.  *    Deactivate an entry on the ping list.
  333.  *
  334.  * Results:
  335.  *    None.
  336.  *
  337.  * Side effects:
  338.  *    List_Insert.
  339.  *
  340.  *----------------------------------------------------------------------
  341.  */
  342.  
  343. static void
  344. Deactivate(pingPtr)
  345.     RecovPing *pingPtr;
  346. {
  347.     LOCK_MONITOR;
  348.  
  349.     if (pingPtr->active) {
  350.     recov_Stats.numHostsPinged--;
  351.     pingPtr->active = FALSE;
  352.     }
  353.  
  354.     UNLOCK_MONITOR;
  355.  
  356. }
  357.  
  358. ENTRY void
  359. RecovPrintPingList()
  360. {
  361.     RecovPing *pingPtr;
  362.  
  363.     LOCK_MONITOR;
  364.  
  365.     if (List_IsEmpty(recovPingList)) {
  366.     return;
  367.     } 
  368.     printf("\nPING_LIST\n");
  369.     for (pingPtr = (RecovPing *)List_First(recovPingList);
  370.         !List_IsAtEnd(recovPingList, (List_Links *)pingPtr);
  371.         pingPtr = (RecovPing *)List_Next((List_Links *)pingPtr)) {
  372.     printf("host %d is %s\n", pingPtr->spriteID,
  373.         pingPtr->active ? "active" : "inactive");
  374.     }
  375.      
  376.     UNLOCK_MONITOR;
  377.  
  378.     return;
  379. }
  380.